#include "CDropItem.h"
#include "../mainctrl.h"

int CDropItem::Drop(CDropItemData& stDropItemData)
{
    if (stDropItemData._ucItemType < ITEM_TYPE_MIN
        || stDropItemData._ucItemType > ITEM_TYPE_MAX)
    {
        return ERROR_ITEM_INVALID_DROP_ITEM_TYPE;
    }

    if (stDropItemData._iItemCount <= 0) 
    {
        return 0;
    }

    switch(stDropItemData._ucItemType)
    {
    case ITEM_TYPE_EXP:
    case ITEM_TYPE_LEVEL_EXP:
        {
            if (_cExpAt < 0)
            {
                _cExpAt = (char)_astDropItem.AddOneItem(stDropItemData);
            }
            else
            {
                _astDropItem[_cExpAt]._iItemCount += stDropItemData._iItemCount;
            }
        }
        break;
    case ITEM_TYPE_SILVER:
    case ITEM_TYPE_LEVEL_SILVER:
        {
            if (_cSilverAt < 0)
            {
                _cSilverAt = (char)_astDropItem.AddOneItem(stDropItemData);
            }
            else
            {
                _astDropItem[_cSilverAt]._iItemCount += stDropItemData._iItemCount;
            }
        }
        break;
    case ITEM_TYPE_GOLD:
        {
            if (_cGoldAt < 0)
            {
                _cGoldAt = (char)_astDropItem.AddOneItem(stDropItemData);
            }
            else
            {
                _astDropItem[_cGoldAt]._iItemCount += stDropItemData._iItemCount;
            }
        }
        break;
    case ITEM_TYPE_HUNLI:
        {
            if (_cHunliAt < 0)
            {
                _cHunliAt = (char)_astDropItem.AddOneItem(stDropItemData);
            }
            else
            {
                _astDropItem[_cHunliAt]._iItemCount += stDropItemData._iItemCount;
            }
        }
        break;
    case ITEM_TYPE_LILIAN:
        {
            if (_cLilianAt < 0)
            {
                _cLilianAt = (char)_astDropItem.AddOneItem(stDropItemData);
            }
            else
            {
                _astDropItem[_cLilianAt]._iItemCount += stDropItemData._iItemCount;
            }
        }
        break;
    case ITEM_TYPE_REPUTATION:
        {
            if (_cReputationAt < 0)
            {
                _cReputationAt = (char)_astDropItem.AddOneItem(stDropItemData);
            }
            else
            {
                _astDropItem[_cReputationAt]._iItemCount += stDropItemData._iItemCount;
            }
        }
        break;

    case ITEM_TYPE_ENERGY:
        {
            if (_cEnergyAt < 0)
            {
                _cEnergyAt = (char)_astDropItem.AddOneItem(stDropItemData);
            }
            else
            {
                _astDropItem[_cEnergyAt]._iItemCount += stDropItemData._iItemCount;
            }            
        }
        break;

    default:
        {
            int i = 0;
            for (; i < _astDropItem.Size(); ++i)
            {
                if (_astDropItem[i]._ucItemType == stDropItemData._ucItemType
                    && _astDropItem[i]._usItemConfigID == stDropItemData._usItemConfigID)
                {
                    _astDropItem[i]._iItemCount += stDropItemData._iItemCount;
                    break;
                }
            }

            if (_astDropItem.Size() >= MAX_DROP_ITEM_PER_TIME)
            {
                CT_ERROR(("%d, %d, %d", stDropItemData._ucItemType, stDropItemData._usItemConfigID, stDropItemData._iItemCount));
                return 0;
            }

            if (i >= _astDropItem.Size())
            {
                _astDropItem.AddOneItem(stDropItemData);
            }
        }
        break;
    }

    return 0;
}

void CDropItem::DropSilver(int iCount)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_SILVER;
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropEnergy(int iCount)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_ENERGY;
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropGold(int iCount)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_GOLD;
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropBattleExp(int iCount)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_EXP;
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropRoleExp(int iCount)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_EXP_ROLE;
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropPartnerExp(int iCount, short shPartnerID)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_EXP_PARTNER;
    stDropItemData._iItemCount = iCount;
    stDropItemData._iData1 = shPartnerID;
    Drop(stDropItemData);
}

void CDropItem::DropHunli(int iCount)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_HUNLI;
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropLilian(int iCount)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_LILIAN;
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropReputation(int iCount)
{
    if (iCount <= 0)
    {
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = ITEM_TYPE_REPUTATION;
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropItem(int iType, int iCount)
{
    if (iType < ITEM_TYPE_MIN || iType > ITEM_TYPE_MAX || iCount <= 0)
    {
        CT_WARNING(("drop item type(%d) count(%d)",iType,iCount));
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = (unsigned char)(iType & 0xFF);
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

void CDropItem::DropItem(unsigned int uiResID, int iType, int iCount)
{
    if (iType < ITEM_TYPE_MIN || iType > ITEM_TYPE_MAX || iCount <= 0)
    {
        CT_WARNING(("drop item type(%d) count(%d)",iType,iCount));
        return;
    }

    CDropItemData stDropItemData;
    stDropItemData._ucItemType = (unsigned char)(iType & 0xFF);
    stDropItemData._usItemConfigID = (unsigned short)(uiResID & 0xFFFF);
    stDropItemData._iItemCount = iCount;
    Drop(stDropItemData);
}

int CDropItem::GetSpaceSize (CDropItemData& stDropItemData)
{
    CItemConfigData stItemConfigData;
    int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetConfig(stDropItemData._ucItemType, stDropItemData._usItemConfigID, stItemConfigData);
    if (iRet)
    {
        CT_ERROR(("%d, %d, %d", stDropItemData._ucItemType, stDropItemData._usItemConfigID, iRet));
        return 0;
    }

    if (stItemConfigData._iUseGrid && stItemConfigData._shMaxCountPerGrid <= 0)
    {
        CT_ERROR(("%d, %d", stItemConfigData._ucItemType, stItemConfigData._shMaxCountPerGrid));
        return 0;
    }

    int iCnt = 0;
    if (stItemConfigData._iUseGrid && stDropItemData._iItemCount > 0)
    {
        iCnt = (stDropItemData._iItemCount / stItemConfigData._shMaxCountPerGrid);
        if (0 != (stDropItemData._iItemCount % stItemConfigData._shMaxCountPerGrid))
        {
            iCnt += 1;
        }
    }

    return iCnt;
}

int CDropItem::GetSpaceSize ()
{
    int iCnt = 0;
    for (int i = 0; i < _astDropItem.Size(); ++i)
    {
        iCnt += GetSpaceSize(_astDropItem[i]);
    }

    return iCnt;
}

void CDropItem::GetPBMsg (unsigned int uiGid, ::google::protobuf::RepeatedPtrField< ::MsgGridItemInfo > & stItems)
{
    for (int i = 0; i < _astDropItem.Size(); i++)
    {
        CDropItemData & stItemData = _astDropItem[i];
        MsgGridItemInfo * pstItem = stItems.Add();
        pstItem->set_item_type(stItemData._ucItemType);
        pstItem->set_item_config_id(stItemData._usItemConfigID);
        pstItem->set_item_count(stItemData._iItemCount);

        if (ITEM_TYPE_CLAN_SILVER == stItemData._ucItemType
            || ITEM_TYPE_CLAN_EXP == stItemData._ucItemType)
        {
            pstItem->set_item_aux_info(CTStringUtils::Uint64ToString(stItemData._iData1, 10));
        }

        if (ITEM_TYPE_EQUIP == stItemData._ucItemType)
        {
            pstItem->set_item_aux_info(CTStringUtils::Uint64ToString(CT_UINT64_MAKE(uiGid, stItemData._iData1), 10));
        }
    }
}

//背包里是否有足够空间, 装下所有物品
bool CDropItem::HasEnoughSpace (unsigned int uiGid)
{
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash.HashFind(uiGid);
    if (iIndex < 0)
    {
        CT_WARNING(("%d", uiGid));   //如果用户不在线的话,尽可能地发给用户,防止物品丢失
        return true;
    }
    CPlayerOnlineData& stPlayerOnlineData = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash[iIndex];

    if (stPlayerOnlineData._stUserStorage.GetBagEmptyGridCount() <  GetSpaceSize())
    {
        return false;
    }

    return true;
}

void CDropItem::SetOssModule (int iModule)
{
    _iModule = iModule;
}

bool CDropItem::Full ()
{
    if (_astDropItem.Size() == _astDropItem.GetCount())
    {
        return true;
    }
    
    return false;
}
